/* eslint-disable @typescript-eslint/no-explicit-any */
import BaseButton from "@/components/base/Button"
import styled from "@emotion/styled"
import { CSSProperties, useMemo } from "react"
import Css from "./css"
import { keyframes } from "@emotion/react"

const ButtonStyled = styled(BaseButton)`
    ${Css.Variables}
    ${Css.Normalize}
    &[data-variant-type="solid"] {
        ${Css.Solid}
    }
    &[data-variant-type="outline"] {
        ${Css.Outline}
    }
    ${Css.Status}
`

type Variant = (
    | {
          type: "solid"
          backgroundColorLeft?: CSSProperties["backgroundColor"]
          backgroundColorRight?: CSSProperties["backgroundColor"]
      }
    | {
          type: "outline"
          backgroundColorLeft?: CSSProperties["backgroundColor"]
          backgroundColorRight?: CSSProperties["backgroundColor"]
          outlineColorLeft?: CSSProperties["borderColor"]
          outlineColorRight?: CSSProperties["borderColor"]
          outlineWidth?: CSSProperties["borderWidth"]
      }
) & {
    borderRadius?: CSSProperties["borderRadius"]
}

type ButtonRegularProps = ExtractStyledProps<typeof ButtonStyled> & {
    variant?: Variant
    loading?: boolean
}

type RegisterCssVarType =
    | "--input-button-background-color-left"
    | "--input-button-background-color-right"
    | "--input-button-border-color-left"
    | "--input-button-border-color-right"
    | "--input-button-border-width"
    | "--input-button-border-radius"

function ButtonRegular(props: ButtonRegularProps) {
    const {
        // 子元素
        children,
        // 變體
        variant: _variant = {
            type: "solid",
            backgroundColorLeft: undefined,
            backgroundColorRight: undefined,
        },
        style: _style,
        disabled: _disabled,
        loading: _loading,
        // 其他屬性
        ...rest
    } = props

    const style = useMemo(() => {
        switch (_variant.type) {
            case "solid": {
                const styles: Partial<Record<RegisterCssVarType, any>> = {
                    ..._style,
                    "--input-button-background-color-left": _variant.backgroundColorLeft,
                    "--input-button-background-color-right": _variant.backgroundColorRight,
                    "--input-button-border-radius": _variant.borderRadius,
                }
                return styles
            }
            case "outline": {
                const styles: Partial<Record<RegisterCssVarType, any>> = {
                    ..._style,
                    "--input-button-background-color-left": _variant.backgroundColorLeft,
                    "--input-button-background-color-right": _variant.backgroundColorRight,
                    "--input-button-border-color-left": _variant.outlineColorLeft,
                    "--input-button-border-color-right": _variant.outlineColorRight,
                    "--input-button-border-width": _variant.outlineWidth,
                    "--input-button-border-radius": _variant.borderRadius,
                }
                return styles
            }
        }
    }, [_variant, _style])

    const attrDataStatus = useMemo(() => {
        if (_disabled) return "disabled"
        if (_loading) return "loading"
        return undefined
    }, [_disabled, _loading])

    return (
        <ButtonStyled
            // 其他屬性
            data-variant-type={_variant.type}
            data-status={attrDataStatus}
            disabled={_disabled || _loading}
            // @ts-ignore
            style={style}
            {...rest}
        >
            {children}
            {attrDataStatus && <Mask data-status={attrDataStatus} />}
        </ButtonStyled>
    )
}

export default ButtonRegular

const LoaderSpin = keyframes`
  from {
    transform: translate(-50%, -50%) rotate(0deg);
  }
  to {
    transform: translate(-50%, -50%) rotate(360deg);
  }
`

const Mask = styled.div`
    z-index: 1;
    pointer-events: none;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(169, 169, 169, 0.488);

    &[data-status="loading"] {
        &::before {
            content: "";
            position: absolute;
            left: 50%;
            top: 50%;
            width: 20rem;
            height: 20rem;
            border: 2rem solid #ffffff;
            border-top-color: transparent;
            border-radius: 50%;
            animation: ${LoaderSpin} 0.8s linear infinite;
        }
    }
`

const ButtonRegularOutlineFixed = styled(ButtonRegular)`
    &[data-variant-type="outline"] {
        -webkit-text-fill-color: #ff3568;
    }
`

export function ButtonRegularOutline(props: ButtonRegularProps) {
    return (
        <ButtonRegularOutlineFixed
            {...props}
            variant={{ type: "outline" }}
        />
    )
}
